using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using LeastPrivilege.CustomBasicAuthentication.Management.Properties;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Client.Win32;

namespace LeastPrivilege.CustomBasicAuthentication.Management
{
    class CustomBasicAuthenticationSettingsDialog : TaskForm
    {
        private bool _internalChange;
        private bool _isDirty;
        private CustomBasicAuthenticationModuleProxy _serviceProxy = null;
        private bool _isLocked = true;
        private Dictionary<string, string> _currentSettings;
        private Dictionary<string, string> _originalSettings;

        // UI elements
        private ManagementPanel _panel;
        private TextBox _txtRealm;
        private Label _lblRealm;
        private Label _lblProvider;
        private TextBox _txtProviderName;
        private System.Windows.Forms.PictureBox _imgBanner;
        private System.Windows.Forms.LinkLabel _lnkBanner;
        private System.Windows.Forms.CheckBox _chkRequireSSL;
        private System.Windows.Forms.CheckBox _chkCachingEnabled;
        private System.Windows.Forms.Label _lblCacheDuration;
        private System.Windows.Forms.NumericUpDown _udCachingDuration;

        public CustomBasicAuthenticationSettingsDialog(
            Module module,
            CustomBasicAuthenticationModuleProxy serviceProxy,
            bool isLocked,
            Dictionary<string, string> settings)
            : base(module)
        {
            // set up UI
            InitializeComponent();
            this.Text = "LeastPrivilege Custom Basic Authentication";
            _lnkBanner.Click += delegate
            {
                Process.Start("http://www.leastprivilege.com");
            };



            // hook up change event handler
            _txtProviderName.TextChanged += _txtProviderName_TextChanged;
            _txtRealm.TextChanged += _txtRealm_TextChanged;
            _chkRequireSSL.CheckedChanged += new EventHandler(_chkRequireSSL_CheckedChanged);
            _chkCachingEnabled.CheckedChanged += new EventHandler(_chkCachingEnabled_CheckedChanged);
            _udCachingDuration.ValueChanged += new EventHandler(_udCachingDuration_ValueChanged);

            // set internal state
            _serviceProxy = serviceProxy;
            _isLocked = isLocked;
            _currentSettings = settings;
            _originalSettings = new Dictionary<string, string>(settings);
        }

        protected override bool CanAccept
        {
            get
            {
                return _isDirty;
            }
        }

        protected override void OnInitialActivated(EventArgs e)
        {
            _internalChange = true;

            _txtRealm.Text = _currentSettings["realm"];
            _txtProviderName.Text = _currentSettings["providerName"];
            _chkCachingEnabled.Checked = bool.Parse(_currentSettings["cachingEnabled"]);
            _chkRequireSSL.Checked = bool.Parse(_currentSettings["requireSSL"]);
            _udCachingDuration.Value = decimal.Parse(_currentSettings["cachingDuration"]);

            _internalChange = false;

            UpdateUI();
        }

        protected override void OnAccept()
        {
            if (_txtRealm.Text.Trim().Length == 0)
            {
                base.ShowError(null, "Must specify a realm", true);
                return;
            }
            else if (_txtProviderName.Text.Trim().Length == 0)
            {
                base.ShowError(null, "Must specify a provider or default", true);
                return;
            }

            // update config async
            StartAsyncTask(OnWorkerDoWork, this.OnWorkerCompleted);
        }

        void OnWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            _serviceProxy.SetConfiguration(_currentSettings);
        }

        void OnWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.DisplayErrorMessage(e.Error, Resources.ResourceManager);
            }
            else
            {
                base.DialogResult = DialogResult.OK;
                base.Close();
            }
        }

        private void UpdateUI()
        {
            // if section is locked, disable text boxes
            _txtRealm.Enabled = !_isLocked;
            _txtProviderName.Enabled = !_isLocked;
            _chkRequireSSL.Enabled = !_isLocked;
            _chkCachingEnabled.Enabled = !_isLocked;
            _udCachingDuration.Enabled = !_isLocked;

            // check if settings have changed since loading
            if (!HaveSettingsChanged())
                _isDirty = false;

            base.UpdateTaskForm();
        }

        private bool HaveSettingsChanged()
        {
            foreach (string key in _currentSettings.Keys)
            {
                if (!string.Equals(_currentSettings[key], _originalSettings[key]))
                {
                    return true;
                }
            }
            return false;
        }

        private void UpdateSetting(string key, string value)
        {
            if (!_internalChange)
            {
                _isDirty = true;
                _currentSettings[key] = value;
                UpdateUI();
            }
        }

        #region Change Handlers
        private void _txtRealm_TextChanged(object sender, EventArgs e)
        {
            UpdateSetting("realm", _txtRealm.Text.Trim());
        }

        private void _txtProviderName_TextChanged(object sender, EventArgs e)
        {
            UpdateSetting("providerName", _txtProviderName.Text.Trim());
        }

        void _udCachingDuration_ValueChanged(object sender, EventArgs e)
        {
            UpdateSetting("cachingDuration", _udCachingDuration.Value.ToString());
        }

        void _chkCachingEnabled_CheckedChanged(object sender, EventArgs e)
        {
            UpdateSetting("cachingEnabled", _chkCachingEnabled.Checked.ToString());
        }

        void _chkRequireSSL_CheckedChanged(object sender, EventArgs e)
        {
            UpdateSetting("requireSSL", _chkRequireSSL.Checked.ToString());   
        }
        #endregion

        #region InitializeComponent
        private void InitializeComponent()
        {
            this._panel = new ManagementPanel();
            this._txtRealm = new System.Windows.Forms.TextBox();
            this._lblRealm = new System.Windows.Forms.Label();
            this._lblProvider = new System.Windows.Forms.Label();
            this._txtProviderName = new System.Windows.Forms.TextBox();
            this._imgBanner = new System.Windows.Forms.PictureBox();
            this._lnkBanner = new System.Windows.Forms.LinkLabel();
            this._chkRequireSSL = new System.Windows.Forms.CheckBox();
            this._chkCachingEnabled = new System.Windows.Forms.CheckBox();
            this._lblCacheDuration = new System.Windows.Forms.Label();
            this._udCachingDuration = new System.Windows.Forms.NumericUpDown();


            // 
            // _txtRealm
            // 
            this._txtRealm.Location = new System.Drawing.Point(26, 71);
            this._txtRealm.Name = "_txtRealm";
            this._txtRealm.Size = new System.Drawing.Size(158, 20);
            this._txtRealm.TabIndex = 1;
            // 
            // _lblRealm
            // 
            this._lblRealm.AutoSize = true;
            this._lblRealm.Location = new System.Drawing.Point(23, 55);
            this._lblRealm.Name = "_lblRealm";
            this._lblRealm.Size = new System.Drawing.Size(37, 13);
            this._lblRealm.TabIndex = 2;
            this._lblRealm.Text = "Realm";
            // 
            // _lblProvider
            // 
            this._lblProvider.AutoSize = true;
            this._lblProvider.Location = new System.Drawing.Point(26, 98);
            this._lblProvider.Name = "_lblProvider";
            this._lblProvider.Size = new System.Drawing.Size(46, 13);
            this._lblProvider.TabIndex = 3;
            this._lblProvider.Text = "Provider";
            // 
            // _txtProviderName
            // 
            this._txtProviderName.Location = new System.Drawing.Point(26, 114);
            this._txtProviderName.Name = "_txtProviderName";
            this._txtProviderName.Size = new System.Drawing.Size(158, 20);
            this._txtProviderName.TabIndex = 4;
            // 
            // _imgBanner
            // 
            this._imgBanner.Image = global::LeastPrivilege.CustomBasicAuthentication.Management.Properties.Resources.favicon16;
            this._imgBanner.Location = new System.Drawing.Point(10, 9);
            this._imgBanner.Name = "_imgBanner";
            this._imgBanner.Size = new System.Drawing.Size(36, 31);
            this._imgBanner.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this._imgBanner.TabIndex = 5;
            this._imgBanner.TabStop = false;
            // 
            // _lnkBanner
            // 
            this._lnkBanner.AutoSize = true;
            this._lnkBanner.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this._lnkBanner.Location = new System.Drawing.Point(50, 18);
            this._lnkBanner.Name = "_lnkBanner";
            this._lnkBanner.Size = new System.Drawing.Size(140, 13);
            this._lnkBanner.TabIndex = 6;
            this._lnkBanner.TabStop = true;
            this._lnkBanner.Text = "www.leastprivilege.com";
            // 
            // _chkRequireSSL
            // 
            this._chkRequireSSL.AutoSize = true;
            this._chkRequireSSL.Location = new System.Drawing.Point(26, 193);
            this._chkRequireSSL.Name = "_chkRequireSSL";
            this._chkRequireSSL.Size = new System.Drawing.Size(86, 17);
            this._chkRequireSSL.TabIndex = 7;
            this._chkRequireSSL.Text = "Require SSL";
            this._chkRequireSSL.UseVisualStyleBackColor = true;
            // 
            // _chkEnableCaching
            // 
            this._chkCachingEnabled.AutoSize = true;
            this._chkCachingEnabled.Location = new System.Drawing.Point(26, 217);
            this._chkCachingEnabled.Name = "_chkEnableCaching";
            this._chkCachingEnabled.Size = new System.Drawing.Size(101, 17);
            this._chkCachingEnabled.TabIndex = 8;
            this._chkCachingEnabled.Text = "Enable Caching";
            this._chkCachingEnabled.UseVisualStyleBackColor = true;
            // 
            // _lblCacheDuration
            // 
            this._lblCacheDuration.AutoSize = true;
            this._lblCacheDuration.Location = new System.Drawing.Point(26, 141);
            this._lblCacheDuration.Name = "_lblCacheDuration";
            this._lblCacheDuration.Size = new System.Drawing.Size(81, 13);
            this._lblCacheDuration.TabIndex = 9;
            this._lblCacheDuration.Text = "Cache Duration";
            // 
            // _udCacheDuration
            // 
            this._udCachingDuration.Location = new System.Drawing.Point(26, 157);
            this._udCachingDuration.Maximum = new decimal(new int[] {
            60,
            0,
            0,
            0});
            this._udCachingDuration.Minimum = new decimal(new int[] {
            1,
            0,
            0,
            0});
            this._udCachingDuration.Name = "_udCacheDuration";
            this._udCachingDuration.Size = new System.Drawing.Size(158, 20);
            this._udCachingDuration.TabIndex = 11;
            this._udCachingDuration.Value = new decimal(new int[] {
            1,
            0,
            0,
            0});

            //
            // _panel
            //
            _panel.Size = new Size(300, 300);
            _panel.Controls.Add(_lblRealm);
            _panel.Controls.Add(_txtRealm);
            _panel.Controls.Add(_lblProvider);
            _panel.Controls.Add(_txtProviderName);
            _panel.Controls.Add(_lnkBanner);
            _panel.Controls.Add(_imgBanner);
            _panel.Controls.Add(_lblCacheDuration);
            _panel.Controls.Add(_udCachingDuration);
            _panel.Controls.Add(_chkRequireSSL);
            _panel.Controls.Add(_chkCachingEnabled);


            base.AutoScaleMode = AutoScaleMode.Font;
            base.ClientSize = new Size(300, 300);

            base.SetContent(_panel);
        }
        #endregion
    }
}
